home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint104s.zoo
/
mint.src
/
fasttext.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-08
|
26KB
|
1,363 lines
/*
Copyright 1992,1992 Eric R. Smith.
Copyright 1992 Atari Corporation.
All rights reserved.
*/
#include "mint.h"
#include "fasttext.h"
#ifdef FASTTEXT
#ifdef __GNUC__
#define INLINE inline
#define ITYPE long /* gcc's optimizer likes 32 bit integers */
#else
#define INLINE
#define ITYPE int
#endif
#define CONDEV (2)
static SCREEN *current;
static void paint P_((SCREEN *, int, char *)),
paint8c P_((SCREEN *, int, char *)),
paint816m P_((SCREEN *, int, char *));
INLINE static void curs_off P_((SCREEN *)), curs_on P_((SCREEN *));
INLINE static void flash P_((SCREEN *));
static void normal_putch P_((SCREEN *, int));
static void escy_putch P_((SCREEN *, int));
static void quote_putch P_((SCREEN *, int));
static char *chartab[256];
#define MAX_PLANES 8
static int fgmask[MAX_PLANES], bgmask[MAX_PLANES];
static long scrnsize;
short hardscroll;
static char *hardbase, *oldbase;
typedef void (*Vfunc) P_((SCREEN *, int));
#define base *((char **)0x44eL)
#define escy1 *((short *)0x4acL)
static Vfunc state;
static short hardline;
static void (*vpaint) P_((SCREEN *, int, char *));
static char *rowoff;
void init P_((void));
void hardware_scroll P_((SCREEN *));
INLINE static char *PLACE P_((SCREEN *, int, int));
INLINE static void gotoxy P_((SCREEN *, int, int));
INLINE static void clrline P_((SCREEN *, int));
INLINE static void clear P_((SCREEN *));
INLINE static void clrchar P_((SCREEN *, int, int));
INLINE static void clrfrom P_((SCREEN *, int, int, int, int));
INLINE static void delete_line P_((SCREEN *, int));
INLINE static void insert_line P_((SCREEN *, int));
static void setbgcol P_((SCREEN *, int));
static void setfgcol P_((SCREEN *, int));
static void putesc P_((SCREEN *, int));
static void escy1_putch P_((SCREEN *, int));
INLINE static void put_ch P_((SCREEN *, int));
/* routines for flashing the cursor for screen v */
/* flash(v): invert the character currently under the cursor */
INLINE static void
flash(v)
SCREEN *v;
{
char *place;
ITYPE i, j, vplanes;
vplanes = v->planes + v->planes;
place = v->cursaddr;
for (j = v->cheight; j > 0; --j) {
for (i = 0; i < vplanes; i+=2)
place[i] = ~place[i];
place += v->planesiz;
}
v->curstimer = v->period;
}
/* make sure the cursor is off */
INLINE
static void
curs_off(v)
SCREEN *v;
{
if (v->flags & CURS_ON) {
if (v->flags & CURS_FSTATE) {
flash(v);
v->flags &= ~CURS_FSTATE;
}
}
}
/* OK, show the cursor again (if appropriate) */
INLINE static void
curs_on(v)
SCREEN *v;
{
if (v->hidecnt) return;
if (v->flags & CURS_ON) {
#if 0
/* if the cursor is flashing, we cheat a little and leave it off
* to be turned on again (if necessary) by the VBL routine
*/
if (v->flags & CURS_FLASH) {
v->curstimer = 2;
return;
}
#endif
if (!(v->flags & CURS_FSTATE)) {
v->flags |= CURS_FSTATE;
flash(v);
}
}
}
void
init()
{
SCREEN *v;
int i, j;
char *data, *foo;
static char chardata[256*16];
register int linelen;
foo = lineA0();
v = (SCREEN *)(foo - 346);
/* Ehem... The screen might be bigger than 32767 bytes.
Let's do some casting...
Erling
*/
linelen = v->linelen;
scrnsize = (v->maxy+1)*(long)linelen;
rowoff = (char *)kmalloc((long)((v->maxy+1) * sizeof(long)));
if (rowoff == 0) {
FATAL("Insufficient memory for screen offset table!");
} else {
long off, *lptr = (long *)rowoff;
for (i=0, off=0; i<=v->maxy; i++) {
*lptr++ = off;
off += linelen;
}
}
if (hardscroll == -1) {
/* request for auto-setting */
hardscroll = v->maxy+1;
}
if (hardscroll > 0) {
if (!hardbase)
hardbase = (char *)(((long)kcore(SCNSIZE(v)+256L)+255L)
& 0xffffff00L);
if (hardbase == 0) {
ALERT("Insufficient memory for hardware scrolling!");
} else {
quickmove(hardbase, base, scrnsize);
v->cursaddr = v->cursaddr + (hardbase - base);
oldbase = base;
base = hardbase;
Setscreen(hardbase, hardbase, -1);
}
}
hardline = 0;
if (v->cheight == 8 && v->planes == 2) {
foo = &chardata[0];
vpaint = paint8c;
for (i = 0; i < 256; i++) {
chartab[i] = foo;
data = v->fontdata + i;
for (j = 0; j < 8; j++) {
*foo++ = *data;
data += v->form_width;
}
}
} else if ((v->cheight == 16 || v->cheight == 8) && v->planes == 1) {
foo = &chardata[0];
vpaint = paint816m;
for (i = 0; i < 256; i++) {
chartab[i] = foo;
data = v->fontdata + i;
for (j = 0; j < v->cheight; j++) {
*foo++ = *data;
data += v->form_width;
}
}
}
else
vpaint = paint;
if (v->hidecnt == 0) {
/*
* make sure the cursor is set up correctly and turned on
*/
(void)Cursconf(0,0); /* turn cursor off */
v->flags &= ~CURS_FSTATE;
/* now turn the cursor on the way we like it */
v->hidecnt = 0;
curs_on(v);
} else {
(void)Cursconf(0,0);
v->flags &= ~CURS_ON;
v->hidecnt = 1;
}
current = v;
/* setup bgmask and fgmask */
setbgcol(v, v->bgcol);
setfgcol(v, v->fgcol);
state = normal_putch;
}
/*
* PLACE(v, x, y): the address corresponding to the upper left hand corner of
* the character at position (x,y) on screen v
*/
INLINE static
char *PLACE(v, x, y)
SCREEN *v;
int x, y;
{
char *place;
int i, j;
place = base + x;
if (y == v->maxy)
place += scrnsize - v->linelen;
else if (y) {
y+=y; /* Make Y into index for longword array. */
y+=y; /* Two word-size adds are faster than a 2-bit shift. */
place += *(long *)(rowoff + y);
}
if ((j = v->planes-1)) {
i = (x & 0xfffe);
do place += i;
while (--j);
}
return place;
}
/*
* paint(v, c, place): put character 'c' at position 'place' on screen
* v. It is assumed that x, y are proper coordinates!
* Specialized versions (paint8c and paint816m) of this routine follow;
* they assume 8 line high characters, medium res. and 8 or 16 line/mono,
* respectively.
*/
static void
paint(v, c, place)
SCREEN *v;
int c;
char *place;
{
char *data, d, doinverse;
ITYPE j, planecount;
int vplanes;
long vform_width, vplanesiz;
vplanes = v->planes;
data = v->fontdata + c;
doinverse = (v->flags & FINVERSE) ? 0xff : 0;
vform_width = v->form_width;
vplanesiz = v->planesiz;
for (j = v->cheight; j > 0; --j) {
d = *data ^ doinverse;
for (planecount = 0; planecount < vplanes; planecount++)
place[planecount << 1]
= ((d & (char) fgmask[planecount])
| (~d & (char) bgmask[planecount]));
place += vplanesiz;
data += vform_width;
}
}
static void
paint8c(v, c, place)
SCREEN *v;
int c;
char *place;
{
char *data;
char d, doinverse;
char bg0, bg1, fg0, fg1;
long vplanesiz;
data = chartab[c];
doinverse = (v->flags & FINVERSE) ? 0xff : 0;
vplanesiz = v->planesiz;
bg0 = bgmask[0];
bg1 = bgmask[1];
fg0 = fgmask[0];
fg1 = fgmask[1];
if (!doinverse && !bg0 && !bg1 && fg0 && fg1) {
/* line 1 */
d = *data++;
*place = d;
place[2] = d;
place += vplanesiz;
/* line 2 */
d = *data++;
*place = d;
place[2] = d;
place += vplanesiz;
/* line 3 */
d = *data++;
*place = d;
place[2] = d;
place += vplanesiz;
/* line 4 */
d = *data++;
*place = d;
place[2] = d;
place += vplanesiz;
/* line 5 */
d = *data++;
*place = d;
place[2] = d;
place += vplanesiz;
/* line 6 */
d = *data++;
*place = d;
place[2] = d;
place += vplanesiz;
/* line 7 */
d = *data++;
*place = d;
place[2] = d;
place += vplanesiz;
/* line 8 */
d = *data;
*place = d;
place[2] = d;
} else {
/* line 1 */
d = *data++ ^ doinverse;
*place = ((d & fg0) | (~d & bg0));
place[2] = ((d & fg1) | (~d & bg1));
place += vplanesiz;
/* line 2 */
d = *data++ ^ doinverse;
*place = ((d & fg0) | (~d & bg0));
place[2] = ((d & fg1) | (~d & bg1));
place += vplanesiz;
/* line 3 */
d = *data++ ^ doinverse;
*place = ((d & fg0) | (~d & bg0));
place[2] = ((d & fg1) | (~d & bg1));
place